import django.utils.timezone as timezone


from channels.generic.websocket import WebsocketConsumer

from app01 import models
from app01.tools.ssh import SSH
from django.http.request import QueryDict

import json
import base64
import re

from app01.models import TerminalLog, RemoteHost


# from django.conf import settings
# try:
#     session_exipry_time = settings.CUSTOM_SESSION_EXIPRY_TIME
# except BaseException:
#     session_exipry_time = 60 * 30


def terminal_log(  hostname, ip, protocol, port, username, cmd, detail, address, start_time):
    event = TerminalLog()
    event.hostname = hostname
    event.ip = ip
    event.protocol = protocol
    event.port = port
    event.username = username
    event.cmd = cmd
    event.detail = detail
    event.address = address
    event.start_time = start_time
    event.save()


class WebSSH(WebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.message = {'status': 0, 'message': None}
        """
        status:
            0: ssh 连接正常, websocket 正常
            1: 发生未知错误, 关闭 ssh 和 websocket 连接

        message:
            status 为 1 时, message 为具体的错误信息
            status 为 0 时, message 为 ssh 返回的数据, 前端页面将获取 ssh 返回的数据并写入终端页面
        """
        # self.session = None
        self.remote_host = None
        self.start_time = None


    def connect(self):
        """
        打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机
        :return:
        """
        self.accept()
        self.start_time = timezone.now()
        query_string = self.scope.get('query_string')
        ssh_args = QueryDict(query_string=query_string, encoding='utf-8')

        width = ssh_args.get('width')
        height = ssh_args.get('height')

        width = int(width)
        height = int(height)

        hostid = ssh_args.get('host')
        hostid = int(hostid)
        # print(type(hostid)) # str
        # print(hostid)

        passwd = ssh_args.get('password')
        user = ssh_args.get('user')

        self.remote_host = models.RemoteHost.objects.get(id=hostid)
        # print(self.remote_host)


        if passwd:
            passwd = base64.b64decode(passwd).decode('utf-8')
        else:
            passwd = None

        #  通过hostid来获取 远程主机的 数据
        host = self.remote_host.ip
        portport = self.remote_host.port
        # user = self.remote_host.remote_user.username
        # passwd = self.remote_host.remote_user.password


        self.ssh = SSH(websocker=self, message=self.message,host=host,user=user,start_time = self.start_time)

        ssh_connect_dict = {
            'host': host,
            'user': user,
            'port': portport,
            'timeout': 30,
            'pty_width': width,
            'pty_height': height,
            'password': passwd
        }

        self.ssh.connect(**ssh_connect_dict)

    def disconnect(self, close_code):
        try:
            if close_code == 3001:
                pass
            else:
                self.ssh.close()
        except:
            pass
        finally:
            # 过滤点结果中的颜色字符
            res = re.sub('(\[\d{2};\d{2}m|\[0m)', '', self.ssh.res)
            # print('结果: ')
            # print(type(res))   #  这个是把 ssh终端上的所有信息都输入出来了，信息有点多
            res_temp = res.replace('[','<br>\n[').replace(']#',"<span style='color:red;font-weight:bold' >]#</span>")
            #  为了让 详细的命令有换行效果

            # print('命令: ')
            # print(self.ssh.cmd)

            # print('') #  这个就是 ssh 上 del按键  在python中 的代码



            # 这里可以把webssh上的输入的命令打印出来，可以写到 数据库中，和登录的用户名、时间一起存放起来，便于知道连接的用户都输入了啥
            # 获得 登陆的用户名   hostname, ip, protocol, port, username, cmd,  address, start_time
            if self.ssh.cmd:
                terminal_log(
                    self.remote_host.hostname,
                    self.remote_host.ip,
                    self.remote_host.get_protocol_display(),
                    self.remote_host.port,
                    self.remote_host.remote_user.username,
                    self.ssh.cmd,
                    res_temp,
                    self.scope['client'][0],
                    self.start_time,
                )

            lx_static_time_exist = models.LuXiangVideo.objects.filter(start_time=self.start_time).exists()
            if lx_static_time_exist:
                models.TerminalLog.objects.filter(start_time=self.start_time).update(video_lx=self.start_time)


    def receive(self, text_data=None, bytes_data=None):
        if text_data is None:
            self.ssh.django_bytes_to_ssh(bytes_data)
        else:
            data = json.loads(text_data)
            if type(data) == dict:
                status = data['status']
                if status == 0:
                    data = data['data']
                    self.ssh.shell(data)
                else:
                    cols = data['cols']
                    rows = data['rows']
                    self.ssh.resize_pty(cols=cols, rows=rows)
